package com.tiancheng.trade.order.mq.config;

import com.tiancheng.trade.order.configuration.CallbackConfig;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.amqp.core.*;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.config.RetryInterceptorBuilder;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.retry.MessageRecoverer;
import org.springframework.amqp.rabbit.retry.RejectAndDontRequeueRecoverer;
import org.springframework.amqp.rabbit.retry.RepublishMessageRecoverer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.retry.RetryPolicy;
import org.springframework.retry.interceptor.RetryOperationsInterceptor;
import org.springframework.retry.policy.CompositeRetryPolicy;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.policy.TimeoutRetryPolicy;

import javax.annotation.Resource;
import java.util.*;

/**
 * 业务系统消息队列配置
 */
@Slf4j
@Getter
@Configuration
public class RabbitMqBusinessConfig {

    @Resource
    private CallbackConfig callbackConfig;

    @Bean
    public Declarables declarables() {
        List<Declarable> declarables = new ArrayList<>();

        // 创建主交换器
        DirectExchange mainExchange = new DirectExchange(callbackConfig.getExchange());
        declarables.add(mainExchange);

        // 为每个业务配置创建队列和绑定
        for (CallbackConfig.BizConfig config : callbackConfig.getConfigs()) {
            // 创建业务队列
            Queue queue = new Queue(config.getQueue(), true);

            // 创建业务队列绑定
            Binding binding = BindingBuilder.bind(queue)
                    .to(mainExchange)
                    .with(config.getRoutingKey());

            // 创建该业务的重试队列
            String retryQueueName = config.getQueue() + ".retry";
            Queue retryQueue = QueueBuilder.durable(retryQueueName)
                    .withArgument("x-dead-letter-exchange", callbackConfig.getExchange())
                    .withArgument("x-dead-letter-routing-key", config.getRoutingKey())
                    // 不设置队列级别的TTL，使用消息级别的TTL
                    .build();

            // 创建重试队列绑定
            DirectExchange retryExchange = new DirectExchange(callbackConfig.getRetryExchange());
            Binding retryBinding = BindingBuilder.bind(retryQueue)
                    .to(retryExchange)
                    .with(config.getRoutingKey());

            declarables.addAll(List.of(queue, binding, retryQueue, retryExchange, retryBinding));
        }

        return new Declarables(declarables);
    }

}
